"""
股票技术分析智能体

基于技术指标和价格走势进行股票技术分析。
"""

from typing import Dict, Any, List, Optional, Union
import json
from agents import BaseAgent, LLMConfig
from tools.stock_data_provider import stock_data_provider
from langchain_core.tools import Tool
import pandas as pd


class StockTechnicalAnalysisAgent(BaseAgent):
    """股票技术分析智能体"""

    def __init__(self, llm_config: Optional[LLMConfig] = None):
        super().__init__(
            name="StockTechnicalAnalysisAgent",
            description="股票技术分析智能体，基于技术指标和价格走势进行分析",
            llm_config=llm_config
        )

    def get_tools(self) -> List[Tool]:
        """获取技术分析所需的工具"""
        return [
            Tool(
                name="get_stock_history_data",
                description="获取股票历史价格数据",
                func=self._get_stock_history_data
            ),
            Tool(
                name="calculate_technical_indicators",
                description="计算股票技术指标（MA、MACD、RSI、BOLL等）",
                func=self._calculate_technical_indicators
            ),
            Tool(
                name="analyze_price_trends",
                description="分析股票价格趋势",
                func=self._analyze_price_trends
            ),
            Tool(
                name="analyze_volume_patterns",
                description="分析股票成交量模式",
                func=self._analyze_volume_patterns
            ),
            Tool(
                name="get_intraday_data",
                description="获取股票分时数据，分析当日走势",
                func=self._get_intraday_data
            ),
            Tool(
                name="analyze_chip_distribution",
                description="分析筹码分布和成本集中度",
                func=self._analyze_chip_distribution
            ),
            Tool(
                name="calculate_advanced_indicators",
                description="计算高级技术指标（KDJ、OBV、ATR等）",
                func=self._calculate_advanced_indicators
            ),
            Tool(
                name="generate_technical_signals",
                description="生成技术分析信号",
                func=self._generate_technical_signals
            )
        ]

    def get_system_prompt(self) -> str:
        return """
        你是专业的股票技术分析智能体，基于价格走势、技术指标和成交量进行全面分析。

        分析框架：
        1. 价格趋势分析：判断上涨/下跌/震荡趋势
        2. 技术指标评估：MA、MACD、RSI、布林带等指标综合判断
        3. 成交量配合度：量价关系分析
        4. 支撑阻力识别：关键价位判断
        5. 技术信号生成：基于多指标综合信号

        输出结构：
        ## 📊 技术指标分析
        - 各指标的具体数值和信号
        - 指标间的配合关系

        ## 📈 趋势判断
        - 短期/中期/长期趋势
        - 趋势强度评估

        ## 🎯 技术信号总结
        - 主要买卖信号
        - 信号强度评分(0-100)
        - 风险提示

        ## ⭐ 技术面评分 (0-10)
        评分标准：
        - 10: 技术面完美，多重指标共振，强烈看好
        - 8-9: 技术面良好，主要指标向好
        - 6-7: 技术面一般，信号中性
        - 4-5: 技术面偏弱，存在风险信号
        - 2-3: 技术面较差，多重看跌信号
        - 0-1: 技术面极差，强烈看空信号

        最终评分：[X/10] - 评分理由

        分析原则：
        - 结合股票所处行业周期和市场环境
        - 考虑技术指标的背离和共振
        - 技术分析需结合基本面共同验证
        - 信号强度取决于多个指标的共振程度

        请提供量化数据支持，避免主观判断。
        """

    async def _get_stock_history_data(self, stock_code: str, days: int = 90) -> str:
        """获取股票历史数据"""
        try:
            self.logger.info(f"开始获取股票{stock_code}的历史数据，时间范围：{days}天")
            from datetime import datetime, timedelta
            end_date = datetime.now().strftime("%Y%m%d")
            start_date = (datetime.now() - timedelta(days=days)).strftime("%Y%m%d")

            self.logger.info(f"调用数据提供商获取数据：start_date={start_date}, end_date={end_date}")
            data = await stock_data_provider.get_stock_history_data(
                stock_code, start_date, end_date
            )
            self.logger.info(f"数据获取完成，数据条数：{len(data) if not data.empty else 0}")

            if data.empty:
                self.logger.warning(f"未找到股票{stock_code}的历史数据")
                return f"未找到股票{stock_code}的历史数据"

            result = f"""
            股票{stock_code}历史数据（最近{days}天）：
            数据条数：{len(data)}
            时间范围：{data['日期'].min()} 至 {data['日期'].max()}
            最新收盘价：{data['收盘'].iloc[-1] if '收盘' in data.columns else 'N/A'}
            最高价：{data['最高'].max() if '最高' in data.columns else 'N/A'}
            最低价：{data['最低'].min() if '最低' in data.columns else 'N/A'}
            平均成交量：{data['成交量'].mean() if '成交量' in data.columns else 'N/A':.0f}
            """
            self.logger.info(f"历史数据处理完成，返回结果长度：{len(result)}")
            return result
        except Exception as e:
            self.logger.error(f"获取历史数据失败: {e}", exc_info=True)
            return f"获取历史数据失败: {e}"

    async def _calculate_technical_indicators(self, stock_code: str) -> str:
        """计算技术指标"""
        try:
            indicators = await stock_data_provider.get_stock_technical_indicators(stock_code)

            if not indicators:
                return f"无法计算股票{stock_code}的技术指标"

            result = f"股票{stock_code}技术指标分析：\n\n"

            # 移动平均线分析
            result += "📈 移动平均线：\n"
            if 'ma5' in indicators and 'ma10' in indicators:
                ma_trend = "多头排列" if indicators['ma5'] > indicators['ma10'] else "空头排列"
                result += f"  MA5: {indicators['ma5']:.2f}, MA10: {indicators['ma10']:.2f} ({ma_trend})\n"

            if 'ma20' in indicators and 'ma30' in indicators:
                ma_trend = "多头排列" if indicators['ma20'] > indicators['ma30'] else "空头排列"
                result += f"  MA20: {indicators['ma20']:.2f}, MA30: {indicators['ma30']:.2f} ({ma_trend})\n"

            # MACD分析
            if 'macd' in indicators and 'macd_signal' in indicators:
                macd_signal = "金叉" if indicators['macd'] > indicators['macd_signal'] else "死叉"
                result += f"\n📊 MACD: {indicators['macd']:.4f}, Signal: {indicators['macd_signal']:.4f} ({macd_signal})\n"
                result += f"  红绿柱: {indicators['macd_hist']:.4f}\n"

            # RSI分析
            if 'rsi' in indicators:
                rsi_level = "超卖" if indicators['rsi'] < 30 else "超买" if indicators['rsi'] > 70 else "正常"
                result += f"\n💪 RSI: {indicators['rsi']:.2f} ({rsi_level})\n"

            # 布林带分析
            if 'bollinger_upper' in indicators and 'bollinger_lower' in indicators:
                result += f"\n🎯 布林带:\n"
                result += f"  上轨: {indicators['bollinger_upper']:.2f}\n"
                result += f"  下轨: {indicators['bollinger_lower']:.2f}\n"

            return result

        except Exception as e:
            return f"计算技术指标失败: {e}"

    async def _analyze_price_trends(self, stock_code: str) -> str:
        """分析价格趋势"""
        try:
            # 获取历史数据
            history_data = await stock_data_provider.get_stock_history_data(stock_code)

            if history_data.empty:
                return f"无法获取股票{stock_code}的价格数据"

            # 计算趋势指标
            prices = history_data['收盘']
            volumes = history_data['成交量']

            # 价格趋势
            recent_prices = prices.tail(20)
            trend_slope = (recent_prices.iloc[-1] - recent_prices.iloc[0]) / len(recent_prices)

            # 成交量趋势
            recent_volumes = volumes.tail(20)
            volume_trend = (recent_volumes.iloc[-1] - recent_volumes.iloc[0]) / recent_volumes.iloc[0]

            # 波动率
            volatility = prices.pct_change().std() * (252 ** 0.5)  # 年化波动率

            result = f"股票{stock_code}价格趋势分析：\n\n"

            # 趋势判断
            if trend_slope > 0.01:
                trend_desc = "📈 强势上涨趋势"
            elif trend_slope < -0.01:
                trend_desc = "📉 强势下跌趋势"
            else:
                trend_desc = "➡️ 横盘震荡走势"

            result += f"趋势分析: {trend_desc}\n"
            result += f"趋势斜率: {trend_slope:.4f}\n\n"

            # 成交量分析
            if volume_trend > 0.2:
                volume_desc = "🔊 成交量放大"
            elif volume_trend < -0.2:
                volume_desc = "🔇 成交量萎缩"
            else:
                volume_desc = "📊 成交量稳定"

            result += f"成交量分析: {volume_desc}\n"
            result += f"成交量变化: {volume_trend:.2%}\n\n"

            # 波动率分析
            if volatility > 0.5:
                vol_desc = "⚠️ 高波动性"
            elif volatility > 0.3:
                vol_desc = "📈 中等波动性"
            else:
                vol_desc = "🛡️ 低波动性"

            result += f"波动率分析: {vol_desc}\n"
            result += f"年化波动率: {volatility:.2%}\n"

            return result

        except Exception as e:
            return f"分析价格趋势失败: {e}"

    async def _analyze_volume_patterns(self, stock_code: str) -> str:
        """分析成交量模式"""
        try:
            history_data = await stock_data_provider.get_stock_history_data(stock_code)

            if history_data.empty:
                return f"无法获取股票{stock_code}的成交量数据"

            volumes = history_data['成交量']
            prices = history_data['收盘']

            # 计算成交量指标
            volume_ma5 = volumes.rolling(5).mean()
            volume_ma20 = volumes.rolling(20).mean()

            # 量价关系分析
            price_changes = prices.pct_change()
            volume_changes = volumes.pct_change()

            # 量价背离检测
            correlation = price_changes.corr(volume_changes)

            result = f"股票{stock_code}成交量模式分析：\n\n"

            # 成交量趋势
            recent_volume = volumes.iloc[-1]
            avg_volume_5 = volume_ma5.iloc[-1]
            avg_volume_20 = volume_ma20.iloc[-1]

            if recent_volume > avg_volume_5 * 1.5:
                volume_signal = "🔥 放量"
            elif recent_volume < avg_volume_5 * 0.7:
                volume_signal = "❄️ 缩量"
            else:
                volume_signal = "📊 正常成交"

            result += f"成交量信号: {volume_signal}\n"
            result += f"当日成交量: {recent_volume:,.0f}\n"
            result += f"5日均量: {avg_volume_5:,.0f}\n"
            result += f"20日均量: {avg_volume_20:,.0f}\n\n"

            # 量价关系
            if correlation > 0.7:
                relation_desc = "✅ 量价配合良好"
            elif correlation < -0.7:
                relation_desc = "⚠️ 量价背离严重"
            else:
                relation_desc = "🤔 量价关系一般"

            result += f"量价关系: {relation_desc}\n"
            result += f"相关系数: {correlation:.3f}\n"

            return result

        except Exception as e:
            return f"分析成交量模式失败: {e}"

    async def _get_intraday_data(self, stock_code: str) -> str:
        """获取分时数据"""
        try:
            import akshare as ak
            
            # 获取分时数据
            intraday_data = ak.stock_zh_a_minute(symbol=stock_code, period='1', adjust='qfq')
            
            if intraday_data.empty:
                return f"无法获取股票{stock_code}的分时数据"
            
            result = f"股票{stock_code}分时数据分析：\n\n"
            
            # 获取最新时间段的数据
            recent_data = intraday_data.tail(60)  # 最近60分钟
            
            # 分析日内波动
            day_high = recent_data['high'].max()
            day_low = recent_data['low'].min()
            current_price = recent_data['close'].iloc[-1]
            open_price = recent_data['open'].iloc[0]
            
            # 计算日内涨跌幅
            day_change = (current_price - open_price) / open_price if open_price > 0 else 0
            
            result += f"📊 分时走势：\n"
            result += f"  开盘价: {open_price:.2f}\n"
            result += f"  当前价: {current_price:.2f}\n"
            result += f"  日内最高: {day_high:.2f}\n"
            result += f"  日内最低: {day_low:.2f}\n"
            result += f"  日内涨跌: {day_change:.2%}\n\n"
            
            # 分析日内趋势
            if day_change > 0.03:
                trend = "🔥 强势上涨"
            elif day_change > 0:
                trend = "📈 温和上涨"
            elif day_change > -0.03:
                trend = "📉 温和下跌"
            else:
                trend = "❄️ 强势下跌"
            
            result += f"趋势判断: {trend}\n"
            
            # 分析成交量变化
            recent_volume = recent_data['volume'].tail(10).mean()
            earlier_volume = recent_data['volume'].head(10).mean()
            volume_change = (recent_volume - earlier_volume) / earlier_volume if earlier_volume > 0 else 0
            
            if volume_change > 0.5:
                volume_trend = "🔊 成交量显著放大"
            elif volume_change > 0.2:
                volume_trend = "📊 成交量放大"
            elif volume_change < -0.2:
                volume_trend = "🔇 成交量萎缩"
            else:
                volume_trend = "➡️ 成交量平稳"
            
            result += f"成交量趋势: {volume_trend}\n"
            
            return result
            
        except Exception as e:
            return f"获取分时数据失败: {e}"

    async def _analyze_chip_distribution(self, stock_code: str) -> str:
        """分析筹码分布"""
        try:
            # 获取历史数据进行筹码分析
            history_data = await stock_data_provider.get_stock_history_data(stock_code)
            
            if history_data.empty:
                return f"无法获取股票{stock_code}的历史数据进行筹码分析"
            
            result = f"股票{stock_code}筹码分布分析：\n\n"
            
            # 计算成交量加权平均价格（VWAP）
            recent_data = history_data.tail(60)  # 最近60个交易日
            
            # VWAP计算
            vwap = (recent_data['收盘'] * recent_data['成交量']).sum() / recent_data['成交量'].sum()
            current_price = recent_data['收盘'].iloc[-1]
            
            result += f"📈 筹码成本分析：\n"
            result += f"  60日成本均价(VWAP): {vwap:.2f}\n"
            result += f"  当前价格: {current_price:.2f}\n"
            result += f"  价格偏离度: {((current_price - vwap) / vwap * 100):+.2f}%\n\n"
            
            # 筹码集中度分析
            # 计算价格分布的标准差
            price_std = recent_data['收盘'].std()
            price_mean = recent_data['收盘'].mean()
            concentration = (price_std / price_mean) * 100 if price_mean > 0 else 0
            
            if concentration < 5:
                concentration_level = "🎯 高度集中"
                concentration_desc = "筹码高度集中，主力控盘明显"
            elif concentration < 10:
                concentration_level = "📊 相对集中"
                concentration_desc = "筹码相对集中，有一定的主力参与"
            elif concentration < 15:
                concentration_level = "📈 分散适中"
                concentration_desc = "筹码分布较为分散，主力控盘不明显"
            else:
                concentration_level = "💫 高度分散"
                concentration_desc = "筹码高度分散，多空分歧较大"
            
            result += f"🎯 筹码集中度: {concentration_level}\n"
            result += f"  集中度指标: {concentration:.2f}%\n"
            result += f"  分析结论: {concentration_desc}\n\n"
            
            # 获利盘分析
            profit_ratio = len(recent_data[recent_data['收盘'] < current_price]) / len(recent_data) * 100
            
            result += f"💰 获利盘分析：\n"
            result += f"  获利盘占比: {profit_ratio:.1f}%\n"
            
            if profit_ratio > 80:
                result += "  ⚠️ 获利盘过多，注意抛压风险\n"
            elif profit_ratio > 60:
                result += "  📊 获利盘较多，可能存在获利回吐\n"
            elif profit_ratio > 40:
                result += "  ✅ 获利盘适中，较为健康\n"
            else:
                result += "  🎯 套牢盘较多，反弹空间较大\n"
            
            return result
            
        except Exception as e:
            return f"分析筹码分布失败: {e}"

    async def _calculate_advanced_indicators(self, stock_code: str) -> str:
        """计算高级技术指标"""
        try:
            history_data = await stock_data_provider.get_stock_history_data(stock_code)
            
            if history_data.empty:
                return f"无法获取股票{stock_code}的历史数据"
            
            result = f"股票{stock_code}高级技术指标：\n\n"
            
            # 计算KDJ指标
            low_9 = history_data['最低'].rolling(9).min()
            high_9 = history_data['最高'].rolling(9).max()
            rsv = (history_data['收盘'] - low_9) / (high_9 - low_9) * 100
            k = rsv.ewm(com=2).mean()
            d = k.ewm(com=2).mean()
            j = 3 * k - 2 * d
            
            k_val = k.iloc[-1]
            d_val = d.iloc[-1]
            j_val = j.iloc[-1]
            
            result += f"📊 KDJ指标：\n"
            result += f"  K值: {k_val:.2f}\n"
            result += f"  D值: {d_val:.2f}\n"
            result += f"  J值: {j_val:.2f}\n"
            
            # KDJ信号判断
            if k_val > d_val and k_val < 80 and d_val < 80:
                kdj_signal = "✅ 金叉形态，买入信号"
            elif k_val < d_val and k_val > 20 and d_val > 20:
                kdj_signal = "❌ 死叉形态，卖出信号"
            elif k_val > 80 and d_val > 80:
                kdj_signal = "⚠️ 超买区域，注意回调"
            elif k_val < 20 and d_val < 20:
                kdj_signal = "🎯 超卖区域，可能反弹"
            else:
                kdj_signal = "➡️ 震荡区间"
            
            result += f"  信号: {kdj_signal}\n\n"
            
            # 计算OBV（能量潮）
            obv = (history_data['成交量'] * ((history_data['收盘'] - history_data['收盘'].shift(1)) > 0).astype(int) - 
                   history_data['成交量'] * ((history_data['收盘'] - history_data['收盘'].shift(1)) < 0).astype(int)).cumsum()
            
            obv_current = obv.iloc[-1]
            obv_ma5 = obv.rolling(5).mean().iloc[-1]
            obv_ma10 = obv.rolling(10).mean().iloc[-1]
            
            result += f"📈 OBV能量潮：\n"
            result += f"  当前OBV: {obv_current:,.0f}\n"
            result += f"  5日均线: {obv_ma5:,.0f}\n"
            result += f"  10日均线: {obv_ma10:,.0f}\n"
            
            if obv_current > obv_ma5 > obv_ma10:
                obv_signal = "✅ OBV多头排列，资金持续流入"
            elif obv_current < obv_ma5 < obv_ma10:
                obv_signal = "❌ OBV空头排列，资金持续流出"
            else:
                obv_signal = "🤔 OBV信号不明确"
            
            result += f"  信号: {obv_signal}\n\n"
            
            # 计算ATR（真实波幅）
            high_low = history_data['最高'] - history_data['最低']
            high_close = abs(history_data['最高'] - history_data['收盘'].shift())
            low_close = abs(history_data['最低'] - history_data['收盘'].shift())
            
            true_range = pd.concat([high_low, high_close, low_close], axis=1).max(axis=1)
            atr = true_range.rolling(14).mean()
            atr_current = atr.iloc[-1]
            
            current_price = history_data['收盘'].iloc[-1]
            atr_percent = (atr_current / current_price) * 100 if current_price > 0 else 0
            
            result += f"📉 ATR真实波幅：\n"
            result += f"  ATR值: {atr_current:.2f}\n"
            result += f"  ATR百分比: {atr_percent:.2f}%\n"
            
            if atr_percent > 3:
                atr_signal = "⚡ 波动剧烈，风险较高"
            elif atr_percent > 2:
                atr_signal = "📊 波动适中"
            else:
                atr_signal = "🛡️ 波动较小，相对稳定"
            
            result += f"  信号: {atr_signal}\n"
            
            return result
            
        except Exception as e:
            return f"计算高级技术指标失败: {e}"


    async def _calculate_technical_score(self, indicators: Dict[str, float], current_price: float) -> float:
        """使用大模型计算技术面评分（0-10分）"""
        try:
            # 构建技术分析数据
            analysis_data = {
                'indicators': indicators,
                'current_price': current_price,
                'ma_signal': self._get_ma_signal(indicators),
                'rsi_level': self._get_rsi_level(indicators),
                'macd_status': self._get_macd_status(indicators),
                'bollinger_position': self._get_bollinger_position(indicators, current_price)
            }
            
            # 使用大模型进行评分
            scoring_prompt = self._get_technical_scoring_prompt(analysis_data)
            llm_response = await self.llm.ainvoke(scoring_prompt)
            
            # 解析大模型响应
            try:
                response_text = llm_response.content if hasattr(llm_response, 'content') else str(llm_response)
                # 提取JSON格式的响应
                if isinstance(response_text, str):
                    # 尝试从文本中提取JSON
                    import re
                    json_match = re.search(r'\{.*\}', response_text, re.DOTALL)
                    if json_match:
                        scoring_result = json.loads(json_match.group())
                    else:
                        # 如果没有找到JSON，尝试解析整个响应
                        scoring_result = json.loads(response_text)
                else:
                    scoring_result = response_text
                
                # 验证scoring_result是字典类型
                if not isinstance(scoring_result, dict):
                    self.logger.warning(f"大模型响应格式错误，期望dict，得到{type(scoring_result)}，使用默认评分")
                    return 5.0
                
                # 验证和调整评分
                score = self._validate_and_clamp_score(scoring_result.get('score', 5))
                return score
                
            except (json.JSONDecodeError, KeyError, AttributeError) as e:
                self.logger.warning(f"大模型响应解析失败，使用默认评分: {str(e)}")
                return 5.0
                
        except Exception as e:
            self.logger.error(f"大模型评分失败: {str(e)}")
            return 5.0





    async def _analyze_trend(self, stock_code: str) -> str:
        """分析趋势方向"""
        try:
            history_data = await stock_data_provider.get_stock_history_data(stock_code)
            if history_data.empty:
                return "无法获取趋势数据"
            
            prices = history_data['收盘']
            
            # 短期趋势（5日）
            short_trend = self._calculate_trend(prices.tail(5))
            # 中期趋势（20日）
            medium_trend = self._calculate_trend(prices.tail(20))
            # 长期趋势（60日）
            long_trend = self._calculate_trend(prices.tail(60))
            
            # 综合趋势判断
            if short_trend > 0.02 and medium_trend > 0.01 and long_trend > 0:
                return "强势上涨趋势"
            elif short_trend < -0.02 and medium_trend < -0.01 and long_trend < 0:
                return "强势下跌趋势"
            elif short_trend > 0 and medium_trend > 0:
                return "温和上涨趋势"
            elif short_trend < 0 and medium_trend < 0:
                return "温和下跌趋势"
            else:
                return "横盘震荡趋势"
                
        except Exception as e:
            self.logger.error(f"趋势分析失败: {e}")
            return "趋势分析失败"

    def _calculate_trend(self, prices: pd.Series) -> float:
        """计算价格趋势斜率"""
        if len(prices) < 2:
            return 0.0
        
        x = range(len(prices))
        y = prices.values
        slope = (len(prices) * sum(x_i * y_i for x_i, y_i in zip(x, y)) - sum(x) * sum(y)) / \
                (len(prices) * sum(x_i**2 for x_i in x) - sum(x)**2)
        
        return slope / prices.iloc[0] if prices.iloc[0] > 0 else 0.0

    def _get_ma_signal(self, indicators: Dict[str, float]) -> str:
        """获取MA信号描述"""
        if 'ma5' in indicators and 'ma10' in indicators:
            if indicators['ma5'] > indicators['ma10']:
                return "金叉"
            else:
                return "死叉"
        return "无信号"

    def _get_rsi_level(self, indicators: Dict[str, float]) -> str:
        """获取RSI水平描述"""
        if 'rsi' in indicators:
            rsi = indicators['rsi']
            if rsi < 30:
                return "超卖反弹"
            elif rsi > 70:
                return "超买回调"
            elif 50 <= rsi <= 70:
                return "强势区间"
            elif 30 <= rsi < 50:
                return "弱势区间"
        return "正常区间"

    def _get_macd_status(self, indicators: Dict[str, float]) -> str:
        """获取MACD状态描述"""
        if 'macd' in indicators and 'macd_signal' in indicators:
            if indicators['macd'] > indicators['macd_signal']:
                return "金叉"
            else:
                return "死叉"
        return "无信号"

    def _calculate_confidence(self, indicators: Dict[str, float]) -> float:
        """计算分析置信度（0-1）"""
        # 基于指标完整性计算置信度
        valid_indicators = 0
        if 'ma5' in indicators and 'ma10' in indicators:
            valid_indicators += 1
        if 'macd' in indicators and 'macd_signal' in indicators:
            valid_indicators += 1
        if 'rsi' in indicators:
            valid_indicators += 1
        if 'bollinger_upper' in indicators and 'bollinger_lower' in indicators:
            valid_indicators += 1
        
        # 根据有效指标数量计算置信度
        if valid_indicators >= 4:
            return 0.9
        elif valid_indicators >= 3:
            return 0.8
        elif valid_indicators >= 2:
            return 0.7
        else:
            return 0.5

    def _generate_summary(self, score: float, trend: str, indicators: Dict[str, float]) -> str:
        """生成技术面摘要"""
        if score >= 8:
            return "技术面整体表现极佳，多重指标共振向上，强烈看好"
        elif score >= 6:
            return "技术面整体表现良好，主要指标表现积极"
        elif score >= 4:
            return "技术面整体表现平稳，指标表现正常"
        elif score >= 2:
            return "技术面整体表现一般，存在一定分歧"
        else:
            return "技术面整体表现较弱，指标表现消极"

    async def _generate_technical_signals(self, stock_code: str, output_format: str = "text") -> Union[Dict[str, Any], str]:
        """生成技术分析信号，支持文本和JSON格式输出"""
        try:
            # 获取技术指标
            indicators = await stock_data_provider.get_stock_technical_indicators(stock_code)

            if not indicators:
                if output_format == "json":
                    return {
                        "error": f"无法生成股票{stock_code}的技术信号",
                        "dimension": "technical",
                        "score": 0.0,
                        "analysis": {
                            "trend_analysis": "数据获取失败",
                            "key_indicators": {},
                            "confidence": 0.0,
                            "summary": "无法获取技术指标数据"
                        },
                        "timestamp": pd.Timestamp.now().isoformat()
                    }
                else:
                    return f"无法生成股票{stock_code}的技术信号"

            # 获取当前价格用于分析
            history_data = await stock_data_provider.get_stock_history_data(stock_code)
            current_price = history_data['收盘'].iloc[-1] if not history_data.empty else 0.0

            # 计算各项分析结果
            trend_analysis = await self._analyze_trend(stock_code)
            technical_score = await self._calculate_technical_score(indicators, current_price)
            confidence = self._calculate_confidence(indicators)
            summary = self._generate_summary(technical_score, trend_analysis, indicators)

            # 构建关键指标信息
            key_indicators = {
                "ma_signal": self._get_ma_signal(indicators),
                "rsi_level": self._get_rsi_level(indicators),
                "macd_status": self._get_macd_status(indicators),
                "bollinger_position": self._get_bollinger_position(indicators, current_price)
            }

            # 根据输出格式返回结果
            if output_format == "json":
                return {
                    "dimension": "technical",
                    "score": technical_score,
                    "analysis": {
                        "trend_analysis": trend_analysis,
                        "key_indicators": key_indicators,
                        "confidence": confidence,
                        "summary": summary
                    },
                    "timestamp": pd.Timestamp.now().isoformat()
                }
            else:
                # 保持向后兼容的文本输出，使用LLM评分而非硬编码计算
                signals = []

                # MA信号（仅描述，不计算分数）
                if 'ma5' in indicators and 'ma10' in indicators:
                    if indicators['ma5'] > indicators['ma10']:
                        signals.append("✅ MA金叉（短期多头）")
                    else:
                        signals.append("❌ MA死叉（短期空头）")

                # MACD信号（仅描述，不计算分数）
                if 'macd' in indicators and 'macd_signal' in indicators:
                    if indicators['macd'] > indicators['macd_signal']:
                        signals.append("✅ MACD金叉")
                    else:
                        signals.append("❌ MACD死叉")

                # RSI信号（仅描述，不计算分数）
                if 'rsi' in indicators:
                    if indicators['rsi'] < 30:
                        signals.append("✅ RSI超卖（买入机会）")
                    elif indicators['rsi'] > 70:
                        signals.append("❌ RSI超买（卖出信号）")
                    else:
                        signals.append("➡️ RSI正常区间")

                # 布林带信号（仅描述，不计算分数）
                if 'bollinger_upper' in indicators and 'bollinger_lower' in indicators:
                    if current_price > indicators['bollinger_upper']:
                        signals.append("⚠️ 突破上轨（可能超买）")
                    elif current_price < indicators['bollinger_lower']:
                        signals.append("🎯 跌破下轨（可能超卖）")

                # 生成综合信号文本，使用LLM生成的评分
                result = f"股票{stock_code}技术分析信号：\n\n"

                for signal in signals:
                    result += f"{signal}\n"

                # 使用LLM生成的评分，而非硬编码计算
                result += f"\n📊 技术面综合评分: {technical_score:.1f}/10\n"
                result += f"📈 趋势分析: {trend_analysis}\n"
                result += f"🎯 置信度: {confidence:.1%}\n\n"
                result += f"💡 评估总结: {summary}\n"

                return result

        except Exception as e:
            error_msg = f"生成技术信号失败: {e}"
            if output_format == "json":
                return {
                    "error": error_msg,
                    "dimension": "technical",
                    "score": 0.0,
                    "analysis": {
                        "trend_analysis": "分析失败",
                        "key_indicators": {},
                        "confidence": 0.0,
                        "summary": error_msg
                    },
                    "timestamp": pd.Timestamp.now().isoformat()
                }
            else:
                return error_msg

    def _get_bollinger_position(self, indicators: Dict[str, float], current_price: float) -> str:
        """获取布林带位置描述"""
        if 'bollinger_upper' in indicators and 'bollinger_lower' in indicators:
            upper = indicators['bollinger_upper']
            lower = indicators['bollinger_lower']
            middle = (upper + lower) / 2
            
            if current_price > upper:
                return "上轨突破"
            elif current_price < lower:
                return "下轨跌破"
            elif current_price > middle:
                return "中轨上方"
            else:
                return "中轨下方"
        return "无信号"


    async def generate_technical_charts(self, stock_code: str) -> Dict[str, Any]:
        """
        生成技术分析图表数据（只返回数据，不渲染）
        
        ✅ 新架构：智能体只返回数据，UI负责渲染
        
        Args:
            stock_code: 股票代码
            
        Returns:
            包含所有图表数据的字典
        """
        try:
            # 获取历史数据
            history_data = await stock_data_provider.get_stock_history_data(stock_code)
            if history_data.empty:
                return {"success": False, "error": "无法获取历史数据"}
            
            self.logger.info(f"✅ 获取历史数据成功，数据量: {len(history_data)}行")
            
            # 计算技术指标
            ma5 = history_data['收盘'].rolling(window=5).mean()
            ma20 = history_data['收盘'].rolling(window=20).mean()
            
            ema12 = history_data['收盘'].ewm(span=12, adjust=False).mean()
            ema26 = history_data['收盘'].ewm(span=26, adjust=False).mean()
            macd = ema12 - ema26
            macd_signal = macd.ewm(span=9, adjust=False).mean()
            macd_hist = macd - macd_signal
            
            delta = history_data['收盘'].diff()
            gain = delta.clip(lower=0).rolling(window=14).mean()
            loss = (-delta).clip(lower=0).rolling(window=14).mean()
            rs = gain / loss.replace(0, 1e-10)
            rsi = 100 - (100 / (1 + rs))
            
            ma20_boll = history_data['收盘'].rolling(window=20).mean()
            std20 = history_data['收盘'].rolling(window=20).std()
            upper_band = ma20_boll + (std20 * 2)
            lower_band = ma20_boll - (std20 * 2)
            
            # ✅ 返回图表数据而不是渲染
            chart_data = {
                "success": True,
                "stock_code": stock_code,
                "candlestick": {
                    "dates": history_data['日期'].tolist(),
                    "open": history_data['开盘'].tolist(),
                    "high": history_data['最高'].tolist(),
                    "low": history_data['最低'].tolist(),
                    "close": history_data['收盘'].tolist(),
                    "volume": history_data['成交量'].tolist()
                },
                "technical_indicators": {
                    "dates": history_data['日期'].tolist(),
                    "close": history_data['收盘'].tolist(),
                    "ma5": ma5.fillna(0).tolist(),
                    "ma20": ma20.fillna(0).tolist(),
                    "macd": macd.fillna(0).tolist(),
                    "macd_signal": macd_signal.fillna(0).tolist(),
                    "macd_hist": macd_hist.fillna(0).tolist(),
                    "rsi": rsi.fillna(50).tolist()
                },
                "price_volume": {
                    "dates": history_data['日期'].tolist(),
                    "close": history_data['收盘'].tolist(),
                    "volume": history_data['成交量'].tolist()
                },
                "bollinger_bands": {
                    "dates": history_data['日期'].tolist(),
                    "close": history_data['收盘'].tolist(),
                    "upper_band": upper_band.fillna(0).tolist(),
                    "middle_band": ma20_boll.fillna(0).tolist(),
                    "lower_band": lower_band.fillna(0).tolist()
                }
            }
            
            self.logger.info(f"✅ 技术分析图表数据生成完成")
            return chart_data
            
        except Exception as e:
            self.logger.error(f"生成技术分析图表数据失败: {e}", exc_info=True)
            return {"success": False, "error": str(e)}


    def _get_technical_scoring_prompt(self, analysis_data: Dict[str, Any]) -> str:
        """生成技术分析评分prompt"""
        prompt = f"""
        请基于以下技术分析数据，给出一个0-10分的综合技术面评分。

        技术指标数据：
        - 当前价格: {analysis_data.get('current_price', 'N/A')}
        - MA信号: {analysis_data.get('ma_signal', 'N/A')}
        - RSI水平: {analysis_data.get('rsi_level', 'N/A')}
        - MACD状态: {analysis_data.get('macd_status', 'N/A')}
        - 布林带位置: {analysis_data.get('bollinger_position', 'N/A')}

        详细指标数据：
        {json.dumps(analysis_data.get('indicators', {}), indent=2, ensure_ascii=False)}

        评分标准（严格使用0-10分制，不是百分制）：
        - 10分: 技术面完美，多重指标共振向上，强烈看好
        - 8-9分: 技术面良好，主要指标表现积极
        - 6-7分: 技术面一般，指标表现中性
        - 4-5分: 技术面偏弱，存在风险信号
        - 2-3分: 技术面较差，多重看跌信号
        - 0-1分: 技术面极差，强烈看空

        **重要提示：请严格返回0-10之间的评分，不要使用百分制（0-100）！**

        请以JSON格式返回结果，包含以下字段：
        {{
            "score": 0-10之间的整数或小数评分（例如：7、8.5等，不是70或85）,
            "reasoning": "详细的评分理由",
            "confidence": 0.0-1.0之间的置信度
        }}

        注意：score字段必须是0-10范围内的数值，不是百分制！
        """
        return prompt

    def _validate_and_clamp_score(self, score: Any) -> int:
        """
        验证和调整评分，确保在0-10范围内
        
        智能处理：
        - 自动检测百分制（0-100）并转换为十分制（0-10）
        - 对超出范围的评分进行合理限制
        - 提供详细的日志信息
        
        Args:
            score: 评分值（可能是整数、浮点数或字符串）
            
        Returns:
            0-10之间的整数评分
        """
        try:
            # 转换为浮点数
            score_float = float(score)
            
            # 智能检测：如果分数>10，可能是百分制，自动转换为十分制
            if score_float > 10:
                self.logger.warning(f"⚠️ 检测到百分制评分{score_float}，自动转换为十分制")
                score_float = score_float / 10.0
            
            # 转换为整数并限制在0-10范围内
            score_int = int(round(score_float))
            clamped_score = max(0, min(10, score_int))
            
            # 如果发生了限制，记录日志
            if score_int != clamped_score:
                self.logger.warning(f"⚠️ 评分{score_int}超出范围，已调整为{clamped_score}")
            
            return clamped_score
            
        except (ValueError, TypeError) as e:
            self.logger.warning(f"⚠️ 评分转换失败: {score}, 错误: {e}, 使用默认值5")
            return 5  # 默认评分

# 全局实例
stock_technical_analysis_agent = StockTechnicalAnalysisAgent()